package com.module.overview.ui.cardHistoryDetails.provider

import android.graphics.Typeface
import android.util.Log
import android.view.View
import android.view.View.OnClickListener
import android.widget.TextView
import androidx.lifecycle.MutableLiveData
import com.chad.library.adapter.base.provider.BaseItemProvider
import com.chad.library.adapter.base.viewholder.BaseViewHolder
import com.common.app.data.bean.overView.HistoryDetailsModel
import com.common.base.app.extras.doOnIOThread
import com.common.base.app.extras.doOnUiThread
import com.common.base.app.extras.otherwise
import com.common.base.app.extras.yes
import com.common.base.utils.JsonUtils
import com.common.base.utils.SpanUtils
import com.common.base.utils.ViewUtils
import com.common.base.utils.ViewUtils.getString
import com.module.ble.data.bean.CusChartData
import com.module.ble.db.table.UserSportRecord
import com.module.ble.db.table.UserStress
import com.module.ble.repo.SportRecordRepo
import com.module.ble.repo.UserStressRepo
import com.module.ble.utils.AllCardTypeConfig
import com.module.ble.widget.StressBarChart
import com.module.overview.R
import java.util.Calendar

/**
 *
 * 作者：sosou
 *
 * 版本：1.0
 *
 * 创建日期：2025/7/10
 *
 * 描述：压力分布卡片
 *
 * 修订历史：完成度100%
 *
 */
class OvPressureDistributionCardProvider(time:Long,
    override val itemViewType: Int = AllCardTypeConfig.TYPE_CARD_PRESSURE_DISTRIBUTION,
    override val layoutId: Int = R.layout.overview_pressure_distribution_crad_provider
) : BaseItemProvider<HistoryDetailsModel>() {

    private var curTime = time

    private var tvAverageStress :TextView? = null
    private var tvAverageStressHint :TextView? = null
    private var tvEarlyMorningCk:TextView? = null
    private var tvMorningCk :TextView? = null
    private var tvAfternoonCk :TextView? = null
    private var tvEveningCk :TextView? = null
    private var stressChart :StressBarChart?= null

    private val earlyMorningStr = getString(R.string.common_rail_unit)
    private val morningStr  = getString(R.string.common_rail_unit)
    private val afternoonStr  = getString(R.string.common_rail_unit)
    private val eveningStr  = getString(R.string.common_rail_unit)

    private var intervalAverageValue  = -1
    private var mSelectType  = 0
    private var totalAverageValue  = -1

    // 设置数据（48个30分钟间隔的数据）
    private val stressData = mutableListOf<CusChartData>()

    init {

        //模拟测试数据
        val currentTime = System.currentTimeMillis()
        val startOfDay = currentTime - (currentTime % (24 * 60 * 60 * 1000)) // 当天0点时间戳

        for (index in 0 until 48) {
            val timeOffset = index * 30 * 60 * 1000L // 每30分钟的时间偏移
            val timestamp = startOfDay + timeOffset

            // 根据实际压力数据设置值（0-100）
            val value = when {
                index < 12 -> (40 + Math.random() * 30).toFloat() // 0-6点
                index < 24 -> (20 + Math.random() * 40).toFloat() // 6-12点
                else -> (10 + Math.random() * 20).toFloat() // 12-24点
            }

            stressData.add(
                CusChartData(
                    createdTime = timestamp,
                    mValue = value,
                    minValue = 0f,
                    dayNum = 0
                )
            )
        }

        // 设置特殊值
        stressData[2] = stressData[2].copy(mValue = 0f)
        stressData[3] = stressData[3].copy(mValue = 20f)
        stressData[4] = stressData[4].copy(mValue = 40f)
        stressData[5] = stressData[5].copy(mValue = 100f)
        stressData[6] = stressData[6].copy(mValue = 110f)
        stressData[7] = stressData[7].copy(mValue = -1f)
        stressData[8] = stressData[8].copy(mValue = -1f)
        stressData[40] = stressData[40].copy(mValue = 77f)
        stressData[15].selectBg = true
        stressData[16].selectBg = true
        stressData[17].selectBg = true
        stressData[19].selectBg = true
    }

    override fun onViewHolderCreated(viewHolder: BaseViewHolder, viewType: Int) {
        tvAverageStress = viewHolder.getView(R.id.tvAverageStress)
        tvAverageStressHint = viewHolder.getView(R.id.tvAverageStressHint)
        tvEarlyMorningCk = viewHolder.getView(R.id.tvEarlyMorningCk)
        tvMorningCk = viewHolder.getView(R.id.tvMorningCk)
        tvAfternoonCk = viewHolder.getView(R.id.tvAfternoonCk)
        tvEveningCk = viewHolder.getView(R.id.tvEveningCk)
        stressChart = viewHolder.getView(R.id.stressChart)
        stressChart?.setOnBarTouchListener(object : StressBarChart.OnBarTouchListener {
            override fun onBarTouched(barIndex: Int, value: Float, timeLabel: String) {
                // 处理触摸到柱子的事件
                tvAverageStress?.let {

                    val stressValueStr = when(value.toInt()){
                        in 0..30 -> getString(R.string.common_pressure_relax_hint)
                        in 31..60 -> getString(R.string.common_pressure_normal_hint)
                        in 61..80 -> getString(R.string.common_pressure_medium_hint)
                        in 81..100 -> getString(R.string.common_pressure_high_hint)
                        else -> getString(R.string.common_rail_unit) // 处理超出范围的情况
                    }

                    SpanUtils.create()
                        .addSection(if (value<=-1) getString(R.string.common_rail_unit) else value.toInt().toString())
                        .addSection(stressValueStr)
                        .setAbsSize(stressValueStr, 16)
                        .showIn(it)
                }

                tvAverageStressHint?.text = timeLabel
            }

            override fun onTouchReleased() {
                // 处理手指离开的事件
                setAverageStressAndHint()
            }

            override fun onIntervalAverageValue(selectType: Int, mValue: Float) {
                intervalAverageValue = mValue.toInt()
                mSelectType = selectType
                setAverageStressAndHint()
            }
        })

        tvEarlyMorningCk?.let { viewIt ->
            viewIt.setOnClickListener {
                viewIt.isSelected.yes {
                    setAllPillarNotSelect()
                }.otherwise {
                    setAllPillarNotSelect()
                    SpanUtils.create()
                        .addForeColorSection(
                            "${getString(R.string.common_early_morning_unit)}\n",
                            ViewUtils.getColor(R.color.c_5282ff)
                        )
                        .addForeColorSection(
                            earlyMorningStr,
                            ViewUtils.getColor(R.color.c_5282ff)
                        )
                        .setAbsSize(earlyMorningStr, 16)
                        .setStyle(earlyMorningStr, Typeface.BOLD)
                        .showIn(viewIt)

                    tvEarlyMorningCk?.isSelected = true
                    tvMorningCk?.isSelected = false
                    tvAfternoonCk?.isSelected = false
                    tvEveningCk?.isSelected = false
                    stressChart?.setSelectType(1)
                }
            }
        }

        tvMorningCk?.let { viewIt ->
            viewIt.setOnClickListener {
                viewIt.isSelected.yes {
                    setAllPillarNotSelect()
                }.otherwise {
                    setAllPillarNotSelect()
                    SpanUtils.create()
                        .addForeColorSection(
                            "${getString(R.string.common_morning_unit)}\n",
                            ViewUtils.getColor(R.color.c_5282ff)
                        )
                        .addForeColorSection(
                            morningStr,
                            ViewUtils.getColor(R.color.c_5282ff)
                        )
                        .setAbsSize(morningStr, 16)
                        .setStyle(morningStr, Typeface.BOLD)
                        .showIn(viewIt)

                    tvMorningCk?.isSelected = true
                    tvEarlyMorningCk?.isSelected = false
                    tvAfternoonCk?.isSelected = false
                    tvEveningCk?.isSelected = false
                    stressChart?.setSelectType(2)
                }
            }
        }

        tvAfternoonCk?.let { viewIt ->
            viewIt.setOnClickListener {
                viewIt.isSelected.yes {
                    setAllPillarNotSelect()
                }.otherwise {
                    setAllPillarNotSelect()
                    SpanUtils.create()
                        .addForeColorSection(
                            "${getString(R.string.common_afternoon_unit)}\n",
                            ViewUtils.getColor(R.color.c_5282ff)
                        )
                        .addForeColorSection(
                            afternoonStr,
                            ViewUtils.getColor(R.color.c_5282ff)
                        )
                        .setAbsSize(afternoonStr, 16)
                        .setStyle(afternoonStr, Typeface.BOLD)
                        .showIn(viewIt)

                    tvAfternoonCk?.isSelected = true
                    tvEarlyMorningCk?.isSelected = false
                    tvMorningCk?.isSelected = false
                    tvEveningCk?.isSelected = false
                    stressChart?.setSelectType(3)
                }
            }
        }

        tvEveningCk?.let { viewIt ->
            viewIt.setOnClickListener {
                viewIt.isSelected.yes {
                    setAllPillarNotSelect()
                }.otherwise {
                    setAllPillarNotSelect()
                    SpanUtils.create()
                        .addForeColorSection(
                            "${getString(R.string.common_evening_unit)}\n",
                            ViewUtils.getColor(R.color.c_5282ff)
                        )
                        .addForeColorSection(
                            eveningStr,
                            ViewUtils.getColor(R.color.c_5282ff)
                        )
                        .setAbsSize(eveningStr, 16)
                        .setStyle(eveningStr, Typeface.BOLD)
                        .showIn(viewIt)

                    tvEveningCk?.isSelected = true
                    tvEarlyMorningCk?.isSelected = false
                    tvMorningCk?.isSelected = false
                    tvAfternoonCk?.isSelected = false
                    stressChart?.setSelectType(4)
                }
            }
        }

        setAllPillarNotSelect()
        super.onViewHolderCreated(viewHolder, viewType)
    }

    override fun convert(helper: BaseViewHolder, item: HistoryDetailsModel) {
//        helper.getView<StressBarChart>(R.id.stressChart).apply {
//            setData(stressData)
////        // 或者设置单个数据点
////        setDataPoint(0, 65f) // 00:00时刻的压力值为65
//        }

        getTheDayStress()
    }

    private fun setAllPillarNotSelect(){

        tvEarlyMorningCk?.let { viewIt ->
            SpanUtils.create()
                .addSection("${getString(R.string.common_early_morning_unit)}\n")
                .addForeColorSection(
                    earlyMorningStr,
                    ViewUtils.getColor(R.color.text_content)
                )
                .setAbsSize(earlyMorningStr, 16)
                .setStyle(earlyMorningStr, Typeface.BOLD)
                .showIn(viewIt)
        }
        tvMorningCk?.let { viewIt ->
            SpanUtils.create()
                .addSection("${getString(R.string.common_morning_unit)}\n")
                .addForeColorSection(
                    morningStr,
                    ViewUtils.getColor(R.color.text_content)
                )
                .setAbsSize(morningStr, 16)
                .setStyle(morningStr, Typeface.BOLD)
                .showIn(viewIt)
        }
        tvAfternoonCk?.let { viewIt ->
            SpanUtils.create()
                .addSection("${getString(R.string.common_afternoon_unit)}\n")
                .addForeColorSection(
                    afternoonStr,
                    ViewUtils.getColor(R.color.text_content)
                )
                .setAbsSize(afternoonStr, 16)
                .setStyle(afternoonStr, Typeface.BOLD)
                .showIn(viewIt)
        }
        tvEveningCk?.let { viewIt ->
            SpanUtils.create()
                .addSection("${getString(R.string.common_evening_unit)}\n")
                .addForeColorSection(
                    eveningStr,
                    ViewUtils.getColor(R.color.text_content)
                )
                .setAbsSize(eveningStr, 16)
                .setStyle(eveningStr, Typeface.BOLD)
                .showIn(viewIt)
        }
        tvEarlyMorningCk?.isSelected = false
        tvMorningCk?.isSelected = false
        tvAfternoonCk?.isSelected = false
        tvEveningCk?.isSelected = false
        stressChart?.setSelectType(0)
    }

    /**
     * 获取当天压力
     */
    private fun getTheDayStress(){
        if (curTime <=0) return

        doOnIOThread {
            //当天压力
            UserStressRepo.instance.findByTimestampTheDay(curTime)?.let { originalListIt->
                //测试数据
//                val testData :List<UserStress> = JsonUtils.fromJsonList("[{\"createdTime\":1755619200000,\"stress\":73},{\"createdTime\":1755620040000,\"stress\":79},{\"createdTime\":1755621000000,\"stress\":96},{\"createdTime\":1755621840000,\"stress\":82},{\"createdTime\":1755622800000,\"stress\":100},{\"createdTime\":1755625440000,\"stress\":76},{\"createdTime\":1755626400000,\"stress\":70},{\"createdTime\":1755629040000,\"stress\":76},{\"createdTime\":1755630000000,\"stress\":70},{\"createdTime\":1755645240000,\"stress\":10}]")
                if (originalListIt.isNullOrEmpty()) return@let

                val listItStr = JsonUtils.toJson(originalListIt)

                // 创建48个时间区间块的CusChartData数组
                val stressListData = mutableListOf<CusChartData>()

                // 获取curTime当天的0点时间戳
                val calendar = Calendar.getInstance()
                calendar.timeInMillis = curTime
                calendar.set(Calendar.HOUR_OF_DAY, 0)
                calendar.set(Calendar.MINUTE, 0)
                calendar.set(Calendar.SECOND, 0)
                calendar.set(Calendar.MILLISECOND, 0)
                val startOfDay = calendar.timeInMillis

                for (index in 0 until 48) {
                    val timeOffset = index * 30 * 60 * 1000L // 每30分钟的时间偏移
                    val intervalStartTime = startOfDay + timeOffset
                    val intervalEndTime = startOfDay + timeOffset + (30 * 60 * 1000L) // 加30分钟作为结束时间

                    stressListData.add(
                        CusChartData(
                            createdTime = intervalStartTime,
                            endTime = intervalEndTime,
                            mValue = -1f,
                            minValue = 0f,
                            dayNum = 0
                        )
                    )
                }

                val stressListDataInitStr = JsonUtils.toJson(stressListData)

                // 将originalListIt中的压力数据按时间区间分组并计算平均值
                for (intervalIndex in stressListData.indices) {
                    val interval = stressListData[intervalIndex]
                    val intervalStart = interval.createdTime
                    val intervalEnd = interval.endTime

                    // 找到属于当前时间区间的所有压力数据
                    val stressValuesInInterval = originalListIt.filter { stressData ->
                        stressData.createdTime in intervalStart until intervalEnd
                    }

                    // 如果该时间区间内有数据，计算平均值
                    if (stressValuesInInterval.isNotEmpty()) {
                        val averageStress = stressValuesInInterval.map { it.stress }.average().toFloat()
                        stressListData[intervalIndex] = stressListData[intervalIndex].copy(mValue = averageStress)
                    }
                }
                totalAverageValue = originalListIt.map { it.stress }.average().toInt()

                doOnUiThread {
                    // 通知图表更新数据
                    stressChart?.setData(stressListData)
                }
                getTheDaySports(stressListData)
            }
        }
    }

    /**
     * 获取当天运动数据
     */
    private fun getTheDaySports(stressList : MutableList<CusChartData>){
        if (curTime <=0) return

        doOnIOThread {
            //当天运动数据
            SportRecordRepo.instance.findAllByDay(curTime)?.let { originalSportsListIt->
//                //测试数据
//                val testList = mutableListOf<UserSportRecord>()
//                val mBean =UserSportRecord()
//                mBean.startTs = 1755620100000
//                mBean.endTs = 1755621900000
//                testList.add(mBean)
//                val mBean2 =UserSportRecord()
//                mBean2.startTs = 1755625500000
//                mBean2.endTs = 1755625680000
//                testList.add(mBean2)
                if (originalSportsListIt.isNullOrEmpty()) return@let

                val listItStr = JsonUtils.toJson(originalSportsListIt)

                // 遍历运动数据记录数组
                originalSportsListIt.forEach { sportRecord ->
                    val sportStartTs = sportRecord.startTs
                    val sportEndTs = sportRecord.endTs

                    // 遍历stressList中的每条数据
                    for (i in stressList.indices) {
                        val stressData = stressList[i]
                        val stressStartTime = stressData.createdTime
                        val stressEndTime = stressData.endTime

                        // 判断压力数据的时间区间是否在运动记录的时间范围内
                        // 如果压力数据的开始时间和结束时间都在运动记录的时间范围内，或者有重叠
                        if ((stressStartTime in sportStartTs until sportEndTs) ||
                            (stressEndTime in (sportStartTs + 1)..sportEndTs) ||
                            (stressStartTime <= sportStartTs && stressEndTime >= sportEndTs)) {

                            // 将该压力数据的selectBg设为true
                            stressList[i] = stressData.copy(selectBg = true)
                        }
                    }
                }

                doOnUiThread {
                    // 通知图表更新数据
                    stressChart?.setData(stressList)
                }
            }
        }
    }

    fun setAverageStress(mAverageStress:Int){

        tvAverageStress?.let {
            val stressValueStr = when(mAverageStress){
                in 0..30 -> getString(R.string.common_pressure_relax_hint)
                in 31..60 -> getString(R.string.common_pressure_normal_hint)
                in 61..80 -> getString(R.string.common_pressure_medium_hint)
                in 81..100 -> getString(R.string.common_pressure_high_hint)
                else -> getString(R.string.common_rail_unit) // 处理超出范围的情况
            }

            SpanUtils.create()
                .addSection(if (mAverageStress<=-1) getString(R.string.common_rail_unit) else mAverageStress.toString())
                .addSection(stressValueStr)
                .setAbsSize(stressValueStr, 16)
                .showIn(it)
        }
    }
    fun setAverageStressAndHint(){
        setAverageStress(if(mSelectType<=0) totalAverageValue else intervalAverageValue)

        tvAverageStressHint?.text = "${when(mSelectType){
            1 -> getString(R.string.common_early_morning_unit)
            2 -> getString(R.string.common_morning_unit)
            3 -> getString(R.string.common_afternoon_unit)
            4 -> getString(R.string.common_evening_unit)
            else ->getString(R.string.common_all_day_hint)
        }
        }${getString(R.string.overview_stress_average_hint)}"

    }
}